package com.winit.openapi.gt.controller;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.winit.common.spi.context.CommandContext;
import com.winit.oms.spi.gt.GlobalTransferOpenApiService;
import com.winit.oms.spi.gt.command.CreateGlobalTransferOpenApiCommand;
import com.winit.oms.spi.gt.vo.CustomerPackageVO;
import com.winit.oms.spi.gt.vo.GlobalTransferOrder;
import com.winit.oms.spi.vo.CreateOrderResult;
import com.winit.openapi.constants.ApiConstant;
import com.winit.openapi.constants.ErrorCode;
import com.winit.openapi.controller.BaseController;
import com.winit.openapi.exception.ApiException;
import com.winit.openapi.model.RequestMsg;
import com.winit.openapi.model.ResponseMsg;
import com.winit.openapi.util.DateUtil;
import com.winit.openapi.util.ValidateUtil;

@Controller
@RequestMapping(value = "/gtOpenApi")
public class OpenGlobalTransferController extends BaseController {

    @Resource
    private GlobalTransferOpenApiService globalTransferOpenApiService;

    /**
     * 提交国际送仓单
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/create")
    public String create(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        CreateGlobalTransferOpenApiCommand command = null;
        Object obj = requestMsg.getData();
        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            // 校验单据信息是否必填、长度、类型
            validateGlobalTransfer(json);
            // 组装command
            command = buildOrderValidateCommand(json);
            command.setCtx(CommandContext.getContext());
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }
        CreateOrderResult result = globalTransferOpenApiService.create(command);

        if (result.isSuccess()) {
            // 返回订单号
            Map<String, String> data = new HashMap<String, String>();
            data.put("orderNo", result.getOrderNo());
            responseMsg.setData(data);
        } else {
            responseMsg.setData(result.getMessageList());
            throw new ApiException(ErrorCode.VALIDTE_ORDER_FAILED);
        }

        return SUCCESS;
    }

    /**
     * 校验单据信息是否必填、长度、类型
     * 
     * @param json
     */
    private void validateGlobalTransfer(JSONObject json) {
        // 必填字段不允许修改为空
        boolean required = true;
        // sellerOrderNo
        boolean sellerOrderNoIsNull = isExistValue(json, "sellerOrderNo");
        if(sellerOrderNoIsNull){
        	ValidateUtil.validMaxLength(json, "sellerOrderNo", 60, required);
        }
        // winitProductCode
        ValidateUtil.validNotNull(json, "winitProductCode");
        ValidateUtil.validMaxLength(json, "winitProductCode", 50, required);
        // warehouseCode
        ValidateUtil.validNotNull(json, "warehouseCode");
        ValidateUtil.validMaxLength(json, "warehouseCode", 30, required);
        // pickServiceCode
        ValidateUtil.validNotNull(json, "pickServiceCode");
        ValidateUtil.validMaxLength(json, "pickServiceCode", 50, required);
        if (json.getString("pickServiceCode").equals("P")) {// winit提货
            // deliveryAddressCode
            ValidateUtil.validNotNull(json, "deliveryAddressCode");
            ValidateUtil.validMaxLength(json, "deliveryAddressCode", 20, required);
        }
        if (json.getString("pickServiceCode").equals("S")) {// 自发物流
            // forecastWarehouseDate
            ValidateUtil.validNotNull(json, "forecastWarehouseDate");
            ValidateUtil.validDateString(json, "forecastWarehouseDate", "yyyy-MM-dd");
            if (json.containsKey("forecastWarehouseDate")) {
                String wDate = new SimpleDateFormat("yyyy-MM-dd").format(json.getDate("forecastWarehouseDate"));
                Date forecastWarehouseDate = DateUtil.parse2Date(wDate, "yyyy-MM-dd");
                String currDay = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
                Date today = DateUtil.parse2Date(currDay, "yyyy-MM-dd");
                if (forecastWarehouseDate.compareTo(today) < 0) {
                    throw new ApiException(ErrorCode.FIELD_DATE_ERROR, wDate);
                }
            }
            // expressNo
            ValidateUtil.validNotNull(json, "expressNo");
            ValidateUtil.validMaxLength(json, "expressNo", 50, required);
            //expressNo殊字符检验
            if (!(json.getString("expressNo")).matches("[^@#$%&(){}<>]{0,}")) {
                throw new ApiException(ErrorCode.NOT_INPUT_SPECHARS, "expressNo");
            }
        }
        // destinationAddressCode
        ValidateUtil.validNotNull(json, "destinationAddressCode");
        ValidateUtil.validMaxLength(json, "destinationAddressCode", 20, required);
        // transportModeCode
        ValidateUtil.validNotNull(json, "transportModeCode");
        ValidateUtil.validMaxLength(json, "transportModeCode", 50, required);

        // 运输方式为【快递】，则不校验航班航次
        if (!json.get("transportModeCode").equals(ApiConstant.TRANSPORTMODECODE)) {
            // flightVoyageId
            ValidateUtil.validNotNull(json, "flightVoyageId");
            ValidateUtil.validMaxLength(json, "flightVoyageId", 8, required);
            // 校验flightVoyageId是否为数字
            if (!ValidateUtil.isLongNumber(json.getString("flightVoyageId"))) {
                throw new ApiException(ErrorCode.NOT_NUMBER_ERROR, "flightVoyageId");
            }
        }

        // importerId
        ValidateUtil.validNotNull(json, "importerId");
        ValidateUtil.validMaxLength(json, "importerId", 10, required);
        // exporterId
        ValidateUtil.validNotNull(json, "exporterId");
        ValidateUtil.validMaxLength(json, "exporterId", 10, required);

        /****************** package *******************/
        // packingList
        ValidateUtil.validNotNull(json, "packingList");
        ValidateUtil.validList(json, "packingList");

        JSONArray array = json.getJSONArray("packingList");
        for (Object object : array) {
            JSONObject pacakge = (JSONObject) object;
            // customerPackageBarcode
            ValidateUtil.validNotNull(pacakge, "customerPackageBarcode");
            ValidateUtil.validMaxLength(pacakge, "customerPackageBarcode", 50, required);
            // customerPackageBarcode是否存在特殊字符
            if (!pacakge.getString("customerPackageBarcode").matches("[^@#$%&(){}<>]{0,}")) {
                throw new ApiException(ErrorCode.NOT_INPUT_SPECHARS, "customerPackageBarcode");
            }
            // declaredCode
            ValidateUtil.validNotNull(pacakge, "declaredCode");
            ValidateUtil.validMaxLength(pacakge, "declaredCode", 500, required);//TODO 和ERP属性长度保持一致
            isExistValue(pacakge, "specification");
            // quantity
            ValidateUtil.validNotNull(pacakge, "quantity");
            positiveNumber(pacakge, "quantity");
            //校验quantity是否为数字
            if (!ValidateUtil.isIntNumber(pacakge.getString("quantity"))) {
                throw new ApiException(ErrorCode.NOT_INTEGER_ERROR, "quantity");
            }
        }
    }

    /**
     * 封装校验订单对象
     * 
     * @param json
     * @return
     */
    private CreateGlobalTransferOpenApiCommand buildOrderValidateCommand(JSONObject json) {
        CreateGlobalTransferOpenApiCommand command = new CreateGlobalTransferOpenApiCommand();
        GlobalTransferOrder order = new GlobalTransferOrder();
        if (json.containsKey("sellerOrderNo")) {
            order.setSellerOrderNo(json.getString("sellerOrderNo"));
        }
        if (json.containsKey("winitProductCode")) {
            order.setWinitProductCode(json.getString("winitProductCode"));
        }
        if (json.containsKey("warehouseCode")) {
            order.setWarehouseCode(json.getString("warehouseCode"));
        }
        if (json.containsKey("pickServiceCode")) {
            order.setPickServiceCode(json.getString("pickServiceCode"));
        }

        if (json.getString("pickServiceCode").equals("P")) {// winit提货
            if (json.containsKey("deliveryAddressCode")) {
                order.setDeliveryAddressCode(json.getString("deliveryAddressCode"));
            }
        }
        if (json.getString("pickServiceCode").equals("S")) {// 自发物流
            if (json.containsKey("forecastWarehouseDate")) {
                order.setForecastWarehouseDate(json.getDate("forecastWarehouseDate"));
            }
            if (json.containsKey("expressNo")) {
                order.setExpressNo(json.getString("expressNo"));
            }
        }
        if (json.containsKey("destinationAddressCode")) {
            order.setDestinationAddressCode(json.getString("destinationAddressCode"));
        }
        if (json.containsKey("transportModeCode")) {
            order.setTransportModeCode(json.getString("transportModeCode"));
        }
        if (json.containsKey("flightVoyageId")) {
            order.setFlightVoyageId(json.getInteger("flightVoyageId"));
        }
        if (json.containsKey("importerId")) {
            order.setImporterId(json.getInteger("importerId"));
        }
        if (json.containsKey("exporterId")) {
            order.setExporterId(json.getInteger("exporterId"));
        }
        JSONArray array = json.getJSONArray("packingList");
        if (array.size() > 0) {
            List<CustomerPackageVO> packageVOList = new ArrayList<CustomerPackageVO>();
            for (Object obj : array) {
                JSONObject pacakge = (JSONObject) obj;
                CustomerPackageVO vo = new CustomerPackageVO();
                vo.setCustomerPackageBarcode(pacakge.getString("customerPackageBarcode"));
                vo.setDeclaredCode(pacakge.getString("declaredCode"));
                vo.setSpecification(pacakge.getString("specification"));
                vo.setQuantity(pacakge.getInteger("quantity"));
                packageVOList.add(vo);
            }
            order.setVoList(packageVOList);
        } else {
            return null;
        }
        command.setGlobalTransferOrder(order);
        return command;
    }

    // 效验重量价格大于0
    public void positiveNumber(JSONObject json, String key) {
        if (isExistValue(json, key) && ValidateUtil.isBigDecimal(json.getString(key))) {
            BigDecimal bd = new BigDecimal(json.getString(key));
            if (bd.compareTo(new BigDecimal("0")) <= 0) {
                throw new ApiException(ErrorCode.FIELD_INPUT_ERROR, key);
            }
        }
    }

    // 效验大于0,批量导入提示
    public void positiveNumberImport(JSONObject json, String key, String xmlKye) {
        if (isExistValue(json, key) && ValidateUtil.isBigDecimal(json.getString(key))) {
            BigDecimal bd = new BigDecimal(json.getString(key));
            if (bd.compareTo(new BigDecimal("0")) <= 0) {
                throw new ApiException(ErrorCode.FIELD_INPUT_ERROR, xmlKye);
            }
        }

    }

    // 判断非必填字段是否有值
    public boolean isExistValue(JSONObject jsonObject, String key) {
        if (jsonObject.containsKey(key)) {
            return !"".equals(jsonObject.getString(key).trim());
        }
        return false;
    }
}
